package opennlp.ccg.grammar;

/**
 * @author D.N. Mehay
 * @version 1.0
 * 
 */ 
public class SynDependency {
	protected String _head;
	protected String _dep;
	protected String _headCat;
	protected String _depCat;
        // The canonical direction (is this an object-like or 
        protected String _direction;
	protected Integer _distance;        
	protected Integer _numVerbsIntervening;
	
	public SynDependency(String head, String dep, String headCat, String depCat, String direction) {
		this(head, dep, headCat, depCat, direction, null, null);
	}
	
	public SynDependency(String head, String dep, String headCat, String depCat, String direction, Integer distance) {
		this(head, dep, headCat, depCat, direction, distance, null);
	}
	
	public SynDependency(String head, String dep, String headCat, String depCat, String direction, Integer distance, Integer verbsIntervening) {
		this._head = head;
		this._dep = dep;		
		this._headCat = headCat;
		this._depCat = depCat;
                this._direction = direction;
		this._distance = distance;                
		this._numVerbsIntervening = verbsIntervening;
	}
	
	public String toString() {
		String res = "";
		res += " " + _head;
		res += " " + _dep;
		res += " " + _headCat;
		res += " " + _depCat;
                res += " " + _direction;
		if(_distance != null) {
			res += " " +_distance;
		}
		if(_numVerbsIntervening != null) {
			res += " " +_numVerbsIntervening;
		}
		return res;
	}
	
	// The hash, in case we need it.
	public int hashCode() {
		int hash = 7;
		hash = 31 * (hash + _head.hashCode());
		hash = 31 * (hash + _dep.hashCode());
		hash = 31 * (hash + _headCat.hashCode());
		hash = 31 * (hash + _depCat.hashCode());
                hash = 31 * (hash + _direction.hashCode());
                
		if(_distance != null) {
			hash = 31 * (hash + _distance.intValue());
		}
		if(_numVerbsIntervening != null) {
			hash = 31 * (hash + _numVerbsIntervening.intValue());
		}
		return hash;
	}
	
	public boolean equals(Object o) {
		if(o == this) {
			return true;
		} else if(o.getClass() != this.getClass()) {
			return false;
		} else {
			
			SynDependency sd = (SynDependency)o;
			// Start with the assumption that they are equal; prove it wrong, if possible.
			boolean retVal = true;
			if(!(_distance == null) || (sd._distance == null)) {
				// Neither is null; compare values.
				retVal = retVal && (_distance.intValue() == sd._distance.intValue());
			} else if((_distance == null) || (sd._distance == null)) {
				// One is null, one isn't.
				return false;
			} else {
				// Both are null, start off with 'true'.
				retVal = true;
			}
			
			if(!(_numVerbsIntervening == null) || (sd._numVerbsIntervening == null)) {
				// Neither is null; compare values.
				retVal = retVal && (_numVerbsIntervening.intValue() == sd._numVerbsIntervening.intValue());
			} else if((_numVerbsIntervening == null) || (sd._numVerbsIntervening == null)) {
				// One is null, one isn't; return false.
				return false;
			} else {
				// Both are null; pass along 'true'
				retVal = retVal && true;
			}
			// Compare the rest of the (guaranteed not to be null) values.
			retVal = retVal &&
				(sd._head.equals(_head) && sd._dep.equals(_dep) &&
				sd._headCat.equals(_headCat) && sd._depCat.equals(_depCat) &&
                                sd._direction.equals(_direction));
			return retVal;	
		}
	}
}
